<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>multi sub Examples (6, Perl6) {...}</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="Perl6_ES5.html">sub Perl6 (*@Examples[5] is copy)</a>&nbsp;&nbsp;>>Next: <a href="Perl6_ES7.html">sub infix:<(7)> ($Perl6, @Examples)</a></p>
<h1>multi sub Examples (6, Perl6) {...}</h1>
<div class='content'>
<p>Category: <a href='Perl6.html'>Perl6</a> &nbsp; Keywords: <b>multi sub Perl6</b></p><h3>Continuation</h3>
接着上一篇 <a href='Perl6_ES5.html'>sub Perl6 (*@Examples[5] is copy)</a> 来接着讲 sub.

<h3>multi sub</h3>
如果你需要一个子程序对于传递进来参数类型的不同而区别对待的话，用 multi sub 是个很简单的方法。<br />
比如定义一个 add 子程序，如果传递进来的是字符串将他们合并起来，数字的话则加起来；如果都不是的话中间用 - 连起来。
<pre>multi sub add (Num $a, Num $b) { return $a + $b; }
multi sub add (Str $a, Str $b) { return $a ~ $b; }
multi sub add ($a, $b) { return $a ~ '-' ~ $b; }

say add(1, 2); # 3
say add('a', 'b'); # ab
say add(0, 'a'); # 0-a</pre>
非常的方便。我想 multi 运用的比较多的是重载 op/操作符。这个下次讲。multi 还能操作方法：multi method

<h3>assuming</h3>
如果你要重复调用很多次子程序，而调用中子程序的某参数都是一样的。你可以使用 assuming（假设某参数）:
<pre>sub multiply ($multiplicand, $multiplier) {
    return $multiplicand * $multiplier;
}
my $six_times = &multiply.assuming(multiplier => 6);

say $six_times(9); # 54
say $six_times(7); # 42

my $seven_times = &multiply.assuming(multiplier => 7);

say $seven_times(9); # 63</pre>
每一个子程序都有 assuming 这方法，我们管这种叫做 Curried Subroutines。<br />

<h3>wrapping</h3>
有些时候你想在一个已定义的子程序里加些东西进去。可你又不方便改源代码（那子程序在一个模块里），而且你想实现原来子程序的功能（Perl 5 中可以试试 <a href='http://search.cpan.org/perldoc?NEXT'>NEXT</a> 模块），拷贝源代码是不方便的做法。<br />
这样的例子在 log 时是非常常见的。在 Perl 6 中可以用 wrap 来实现这功能：
<pre>sub someaction (*@a) {
    say @a;
}

my $id = &someaction.wrap( {
    say 'start someaction'; # log start
    call;
    say 'end someaction'; # log end
} );

&someaction(1,2);</pre>
这样我们就非常简单的加进去了 log 功能。<br />
这里的 call 是调用原子程序。<br />
而如果你不想要这功能的时候，可以使用 unwrap 来去掉。
<pre>&someaction.unwrap($id);</pre>
当然，如果你是临时想重新定义改子程序的话，可以使用 temp （不仅对子程序，对变量也是有用的。）
<pre>{
   temp &someaction.wrap( {...} );
   # ...
}</pre>
wrap 可以多重嵌套

<h3>To be continued</h3>
See u next time.</div>
<p><&lt;Previous: <a href="Perl6_ES5.html">sub Perl6 (*@Examples[5] is copy)</a>&nbsp;&nbsp;>>Next: <a href="Perl6_ES7.html">sub infix:<(7)> ($Perl6, @Examples)</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=multi%20sub%20Examples%20(6,%20Perl6)%20%7B...%7D&url=http://www.fayland.org/journal/Perl6_ES6.html'>+Del.icio.us</a></p>
<strong>Related items</strong>
<ul><li><a href='Perl6_ES5.html'>sub Perl6 (*@Examples[5] is copy)</a> < <span class='digit'>2005-05-22 15:37:26</span> ></li><li><a href='Perl6_ES16.html'>my subtype Examples16 of Perl6 where /^kissu$/</a> < <span class='digit'>2005-06-04 23:59:29</span> ></li><li><a href='prototype_FormSubmit.html'>用 prototype 来写 Ctrl+Enter 提交表单</a> < <span class='digit'>2005-11-25 21:44:37</span> ></li><li><a href='svk_notes.html'>svk 的一些使用纪录</a> < <span class='digit'>2005-12-03 00:45:11</span> ></li></ul>
Created on <span class="digit">2005-05-23 22:43:33</span>, Last modified on <span class="digit">2005-05-23 22:55:05</span><br />
Copyright 2004-2005 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.62.
</body>
</html>